#ifndef AESCRYPTO_H
#define AESCRYPTO_H

#include <string>
#include "openssl/evp.h"
#include "Hash.h" // 哈希类
#include <map>
using namespace std;

// 对称加密算法AES
class AesCrypto {
public:
    using algorithmFunc = const EVP_CIPHER*(*)(void);

    // 对称加密算法AES的种类: 以[5种分组密码的模式]和[3种密匙长度]为依据
    enum Algorithm {
        AES_ECB_128, AES_CBC_128, AES_CFB_128, AES_OFB_128, AES_CTR_128, // 16byte
        AES_ECB_192, AES_CBC_192, AES_CFB_192, AES_OFB_192, AES_CTR_192, // 24byte
        AES_ECB_256, AES_CBC_256, AES_CFB_256, AES_OFB_256, AES_CTR_256  // 32byte
    };

    enum CryptoType { DECRYPTO = 0, ENCRYPTO = 1 }; // 加解密

    AesCrypto(Algorithm algorithm, string key);
    ~AesCrypto();

    string enCrypto(string text); // 加密
    string deCrypto(string text); // 解密
private:
    string aesCrypto(string text, CryptoType type); // [加密or解密]的具体实现
    void generateIvec(unsigned char* ivec); // 密匙 --[哈希算法]--> 哈希值 -> ivec(初始向量)

    Algorithm _type; // 对称加密算法的类型
    string _key;     // 密匙

    // 对称加密算法AES: 采用[不同分组密码模式]和[不同密匙长度]的算法类型
    const map<Algorithm, algorithmFunc> _algorithmMap = {
        {AES_ECB_128, EVP_aes_128_ecb},
        {AES_CBC_128, EVP_aes_128_cbc},
        {AES_CFB_128, EVP_aes_128_cfb128},
        {AES_OFB_128, EVP_aes_128_ofb},
        {AES_CTR_128, EVP_aes_128_ctr},
        {AES_ECB_192, EVP_aes_192_ecb},
        {AES_CBC_192, EVP_aes_192_cbc},
        {AES_CFB_192, EVP_aes_192_cfb128},
        {AES_OFB_192, EVP_aes_192_ofb},
        {AES_CTR_192, EVP_aes_192_ctr},
        {AES_ECB_256, EVP_aes_256_ecb},
        {AES_CBC_256, EVP_aes_256_cbc},
        {AES_CFB_256, EVP_aes_256_cfb128},
        {AES_OFB_256, EVP_aes_256_ofb},
        {AES_CTR_256, EVP_aes_256_ctr}
    };
};
#endif //AESCRYPTO_H
